$TITLE ('RTX-51 TASK BLOCK FUNCTIONS')
$SYMBOLS
$NOXREF
$NOCOND
$NOMOD51
$NORB
$PAGELENGTH(80) PAGEWIDTH(110)
;************************************************************************
;*									*
;*    R T X - 5 1  :   TASK BLOCK FUNCTIONS                             *
;*							     		*
;*----------------------------------------------------------------------*
;*                                                                      *
;*    Filename     :   RTXBLOCK.A51                                     *
;*    Language     :   Keil A-51                                        *
;*    Dev. system  :   Keil uVision2                                    *
;*    Targetsystem :   Any system based upon 8051 up                    *
;*                                                                      *
;*    Purpose      :   Functions for task blocking (context save).      *
;*								     	*
;*----------------------------------------------------------------------*
;* Rev. |  Released   | Programmer    | Comments                        *
;*----------------------------------------------------------------------*
;* 0.1  |  16.1.1990  | E. Glatz      | New for V3.20                   *
;* 0.2  |  27.3.1991  | Th. Fischler  | C-51 parameter passing for V4.0 *
;*      |   8.5.1991  |               | Reentrant Stack in the Kontext  *
;*      |  18.9.1991  |               | Restore of supervisor-mode flag *
;*      |             |               | for suspended tasks             *
;* 0.3  |  20.11.1991 | Th. Fischler  | Error with unsuspend of system- *
;*      |             |               | clock-handler corrected         *
;*      |  14.04.1992 |               | Changes for Code-Bank-Switching *
;*      |             |               | added                           *
;* 0.4  |  27.10.1992 | Th. Fischler  | Reading P2 problems solved      *
;* 5.00 |  13.10.1994 | E. Glatz      | Comments                        *
;* 7.00 |  13.11.2001 | T. Mueller    | Page addressing configurable    *
;************************************************************************
;*    Copyright 1991 .. 2001 METTLER  &  FUCHS  AG,  CH-8953 Dietikon   *
;************************************************************************

$INCLUDE (RTXDEBUG.INC)
$INCLUDE (RTXIMASK.INC)

;*----------------------------------------------------------------------*
;*	I M P O R T S
;*----------------------------------------------------------------------*

$INCLUDE (RTXCONST.INC)
$INCLUDE (RTXEXTRN.INC)

;	FROM REDISPATCH
EXTRN    CODE  (?RTX_REDISPATCH)
;       FROM RTXCONF
EXTRN    DATA  (?RTX_SAVE_INT_BANK, ?B_CURRENTBANK, ?RTX_PAGE_OUT_REG)
EXTRN    CODE  (?RTX_SWITCHBANK)


;*----------------------------------------------------------------------*
;*	E X P O R T S
;*----------------------------------------------------------------------*

PUBLIC  ?RTX_NDBLOCK, ?RTX_DBLOCK


;*----------------------------------------------------------------------*
;*      D U M M Y - S T A C K   D E C L A R A T I O N
;*----------------------------------------------------------------------*

?STACK         SEGMENT  IDATA
               RSEG     ?STACK
               DS 1



;*----------------------------------------------------------------------*
;*	P R O C E D U R E S
;*----------------------------------------------------------------------*

;*----------------------------------------------------------------------*
;*      ? R T X _ D B L O C K
;*----------------------------------------------------------------------*
;*      Block function for fast tasks (driver tasks).
;*      Only context saving is done, no operations on task state are
;*      performed.
;*      If a task was suspended due to the calling fast tasks activation,
;*      it will be unsuspended, else the dispatcher will be entered.
;*      Saved context data is:
;*      - SP
;*      - P2 (?RTX_P2_MIR) and ?RTX_PBP (reentrant stack)
;*      - Code-Bank if bankswitching is enabled
;*      R7 is set to NIL_EVENT.
;*----------------------------------------------------------------------*
;*      Input:   - ?RTX_RUNNING_TID task id of task to be blocked
;*               - All task interrupts are disabled !
;*
;*      Output:  - unsuspended task or dispatcher entered
;*               - ACC and DPTR changed
;*----------------------------------------------------------------------*

?RTX?DBLOCK?RTXBLOCK  SEGMENT CODE
                      RSEG    ?RTX?DBLOCK?RTXBLOCK

?RTX_DBLOCK:
               MOV   A, R0                      ; save R0
               JB    ?RTX_RUNNING_TID.1, DBLOCK3
               JB    ?RTX_RUNNING_TID.0, DBLOCK2

DBLOCK1:       MOV   R0, #?RTX_FTASKDATA?1
               JMP   DB_CONT

DBLOCK2:       MOV   R0, #?RTX_FTASKDATA?2
               JMP   DB_CONT

DBLOCK3:       MOV   R0, #?RTX_FTASKDATA?3

DB_CONT:       MOV   @R0, SP
               INC   R0
               MOV   @R0, ?RTX_P2_MIR
               INC   R0
               MOV   @R0, ?RTX_PBP
               JNB   ?RTX_BANKSW, UNSUSPEND
               INC   R0
               MOV   @R0, ?B_CURRENTBANK

UNSUSPEND:     MOV   R0, A
               ; Check if a task has to be
               ; unsuspended
               MOV   A, ?RTX_SAVE_INT_TID
               CJNE  A, #NIL_TID, SUSP_EXST
               MOV   R7, #NIL_EVENT             ; Set returnvalue of the
                                                ; active task to NIL_EVENT
               JMP   NO

SUSP_EXST:     ; Restore context of suspended task
               $IF (DBG = 02H)
                  MOV   DPTR, #?RTX_DEBUG_TID
                  MOV   A,  ?RTX_SAVE_INT_TID
                  MOVX  @DPTR, A
               $ENDIF

               ; Check if bankswitch required
               JNB   ?RTX_BANKSW, NOT_B
               MOV   A, ?RTX_SAVE_INT_BANK
               GLOBAL_INT_DISABLE
               CALL  ?RTX_SWITCHBANK
               GLOBAL_INT_ENABLE
NOT_B:         MOV   R7, #NIL_EVENT             ; Set returnvalue of the
                                                ; active task to NIL_EVENT
               MOV   A,   ?RTX_SAVE_INT_A
               MOV   B,   ?RTX_SAVE_INT_B
               MOV   DPH, ?RTX_SAVE_INT_DPH
               MOV   DPL, ?RTX_SAVE_INT_DPL
               MOV   C, ?RTX_SAVE_INT_SV
               MOV   ?RTX_SUPERVISOR_MODE, C
               MOV   PSW, ?RTX_SAVE_INT_PSW
               MOV   SP,  ?RTX_SAVE_INT_SP
               JNB   ?RTX_REENTRANTFLAG, NOT_R
               GLOBAL_INT_DISABLE
               MOV   ?RTX_PAGE_OUT_REG, ?RTX_SAVE_INT_RSP
               MOV   ?RTX_P2_MIR, ?RTX_SAVE_INT_RSP
               MOV   ?RTX_PBP, ?RTX_SAVE_INT_RSP+1
               GLOBAL_INT_ENABLE
NOT_R:         MOV   ?RTX_RUNNING_TID, ?RTX_SAVE_INT_TID

               MOV   ?RTX_SAVE_INT_TID, #NIL_TID ; Store NIL value

               ; Check if suspended task has supervisor mode
               JB    ?RTX_SUPERVISOR_MODE, YES  ; Jump if YES
               ; NO:
               ; It's okay to redispatch
               SETB  ?RTX_FULL_CONTEXT          ; If resign save full context
               JMP   ?RTX_REDISPATCH
;
;       No suspended task exists, enter dispatcher
;  
NO:            CLR   ?RTX_PROCESSOR_ALLOCATED   ; Proc. is deallocated now
               JMP   ?RTX_REDISPATCH
;
;	Suspended task exists and is in supervisor mode.
;	It is (always) a standard task (=non driver task) interrupted during 
;       system function execution or the system-clock handler.
;       Instead of entering the dispatcher, we just request a redispatch.
;       As soon as the restarted standard task gets at the end of the system
;       call it is executing, the dispatcher will be entered.
;
YES:           SETB  ?RTX_REQ_REDISPATCH        ; Request a redispatch
               JNB   ?RTX_RUNNING_TID.5, NON_D
               ; Suspended Task is the system-clock handler which has
               ; interrupted the idle mode
               ; clear processor_allocated
               CLR   ?RTX_PROCESSOR_ALLOCATED

NON_D:         RTX_ALLOW_DRV_INT                ; Because suspended task is
                                                ; executing a system function
                                                ; standard task interrupts
                                                ; are not allowed !
               RET




;*----------------------------------------------------------------------*
;*      ? R T X _ N D B L O C K
;*----------------------------------------------------------------------*
;*      Block function for standard tasks (=non driver tasks).
;*      Only context saving is done, no operations on task state are
;*      performed.
;*      Saved context data is:
;*      - SP
;*      - Current stack contents
;*      - P2 (?RTX_P2_MIR) and ?RTX_PBP (reentrant stack)
;*      - Context type
;*      - R4/R5/R6 if R3=1 on entry
;*      - Code-Bank: for standard tasks (non driver tasks) the banknumber
;*        is always stored)
;*      The saved R7 is set to NIL_EVENT.
;*----------------------------------------------------------------------*
;*      Input:   - ?RTX_RUNNING_TID task id of task to be blocked
;*               - R3 = 1: save R4/R5/R6
;*                    = 0: do not save R4/R5/R6
;*               - All standard task interrupts are disabled.
;*                 This section is never entered by fast tasks (driver tasks),
;*                 therefore fast task interrupts may stay enabled.
;*
;*      Output:  - Redispatch initiated (calls directly dispatcher)
;*               - ACC, B and DPTR changed
;*----------------------------------------------------------------------*

?RTX?NDBLOCK?RTXBLOCK  SEGMENT CODE
                       RSEG    ?RTX?NDBLOCK?RTXBLOCK

?RTX_NDBLOCK:  MOV   A, ?RTX_RUNNING_TID        ; Extract standard task
               ANL   A, #00FH                   ; (non driver task) no
               MOV   B, A                       ; save task-no
               MOV   A, #LOW(?RTX_KNTXT_PTR_TABLE)
               ADD   A, B
               ADD   A, B
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_KNTXT_PTR_TABLE)
               MOVX  A, @DPTR
               MOV   B, A
               INC   DPL
               MOVX  A, @DPTR
               MOV   DPL, A
               MOV   DPH, B                     ; DPTR -> kntxt ACC

               ; Saved context(R7)=NIL_EVENT
               MOV   A, #NIL_EVENT
               INC   DPL
               MOVX  @DPTR, A
               ; Prepare DPTR-offset for SP
               MOV   B, #0CH

               ; Check if save of R6..R4 requested
               CJNE  R3, #1, STACK_SAV
               ; Store R6
               INC   DPL
               MOV   A, R6
               MOVX  @DPTR, A
               ; Store R5
               INC   DPL
               MOV   A, R5
               MOVX  @DPTR, A
               ; Store R4
               INC   DPL
               MOV   A, R4
               MOVX  @DPTR, A
               ; Correct DPTR-offset for SP
               MOV   B, #09H

STACK_SAV:
               MOV   A, DPL
               ADD   A, B                       ; Move DPTR to context(SP)
               MOV   DPL, A                     ; (DPTR) --> context (SP)

               ; Store SP
               MOV   A, SP
               MOVX  @DPTR, A
               INC   DPL
               ; Store Context-Type = REDUCED
               MOV   A, #REDUCED
               MOVX  @DPTR, A
               INC   DPL
               ; Store reentrant stack-pointer
               MOV   A, ?RTX_P2_MIR
               MOVX  @DPTR, A
               INC   DPL
               MOV   A, ?RTX_PBP
               MOVX  @DPTR, A
               INC   DPL
               JNB   ?RTX_BANKSW, NO_BA
               MOV   A, ?B_CURRENTBANK
               MOVX  @DPTR, A                   ; DPTR -> stack context-1

               ; Calculate stack byte count
NO_BA:         MOV   A, SP
               CLR   C
               SUBB  A, #?STACK-1
               MOV   B, A                       ; B := stack byte count

               ; Save stack in stack-context
               MOV   A, DPL
               ADD   A, B
               MOV   DPL, A                     ; (DPTR) --> stack context
SAVE_STACK:    POP   ACC                        ; Store stack content
               MOVX  @DPTR, A
               DEC   DPL
               DJNZ  B, SAVE_STACK

               RTX_EXCLUDE_INT
               CLR   ?RTX_PROCESSOR_ALLOCATED   ; Proc. is deallocated
               JMP   ?RTX_REDISPATCH            ; Full_context flag must not
                                                ; be set as proc.is deallocated
;
;   END OF MODULE
;
	END
